/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.icee.myth.server.gm;

import com.google.gson.JsonSyntaxException;
import com.icee.myth.common.messageQueue.DBMessageQueue;
import com.icee.myth.log.GameLogger;
import com.icee.myth.log.message.FileDebugGameLogMessage;
import com.icee.myth.log.message.builder.GameLogMessageBuilder;
import com.icee.myth.protobuf.ExternalCommonProtocol.MailContentProto;
import com.icee.myth.protobuf.ExternalCommonProtocol.IntStringProto;
import com.icee.myth.protobuf.ExternalCommonProtocol.RewardProto;
import com.icee.myth.protobuf.ExternalCommonProtocol.S2CTalkProto;
import com.icee.myth.protobuf.RpcServiceProtocol.GMConsumerLogProto;
import com.icee.myth.protobuf.RpcServiceProtocol.GMMailProto;
import com.icee.myth.protobuf.builder.ClientToMapBuilder;
import com.icee.myth.server.GameServer;
import com.icee.myth.server.PlayerContext;
import com.icee.myth.server.activity.cardDrawActivity.JSONCardDrawActivityTemplates;
import com.icee.myth.server.activity.normalActivity.NormalActivityTemplate;
import com.icee.myth.server.activity.normalActivity.NormalActivityTemplates;
import com.icee.myth.server.activity.stageActivity.JSONStageActivityTemplates;
import com.icee.myth.server.message.dbMessage.AddNormalActivityDBMessage;
import com.icee.myth.server.message.dbMessage.DeleteNormalActivityDBMessage;
import com.icee.myth.server.message.dbMessage.builder.MapDBMessageBuilder;
import com.icee.myth.server.message.serverMessage.gmMessage.AddMailMessage;
import com.icee.myth.server.message.serverMessage.gmMessage.AddNormalActivityMessage;
import com.icee.myth.server.message.serverMessage.gmMessage.BroadcastMessage;
import com.icee.myth.server.message.serverMessage.gmMessage.DeleteNormalActivityMessage;
import com.icee.myth.server.message.serverMessage.gmMessage.GMMessage;
import com.icee.myth.server.message.serverMessage.gmMessage.GetConsumerLogMessage;
import com.icee.myth.server.message.serverMessage.gmMessage.GetOnlinePlayerCountMessage;
import com.icee.myth.server.message.serverMessage.gmMessage.GetOnlinePlayerIdsMessage;
import com.icee.myth.server.message.serverMessage.gmMessage.KickPlayerMessage;
import com.icee.myth.server.message.serverMessage.gmMessage.RpcModifyPlayerMessage;
import com.icee.myth.server.message.serverMessage.gmMessage.SetCardDrawActivityMessage;
import com.icee.myth.server.message.serverMessage.gmMessage.SetStageActivityMessage;
import com.icee.myth.server.message.serverMessage.gmMessage.ShutUpMessage;
import com.icee.myth.server.player.MapPlayer;
import com.icee.myth.utils.Consts;
import com.icee.myth.utils.JSONHelper;
import com.icee.myth.utils.StackTraceUtil;

/**
 *
 * @author liuxianke
 */
public class GMHandler {
    public static void handle(GMMessage message) {
        switch (message.subType) {
            case GM_GET_ONLINE_PLAYER_COUNT: {
                GetOnlinePlayerCountMessage getOnlinePlayerCountMessage = (GetOnlinePlayerCountMessage)message;
                synchronized(getOnlinePlayerCountMessage) {
                    getOnlinePlayerCountMessage.setValue(GameServer.INSTANCE.players.size());
                    getOnlinePlayerCountMessage.notify();
                }
                break;
            }
            case GM_GET_ONLINE_PLAYER_IDS: {
                GetOnlinePlayerIdsMessage getOnlinePlayerIdsMessage = (GetOnlinePlayerIdsMessage)message;
                synchronized(getOnlinePlayerIdsMessage) {
                    for (MapPlayer player : GameServer.INSTANCE.players.values()) {
                        if (player.human != null) {
                            getOnlinePlayerIdsMessage.addPlayerId(player.getId());
                        }
                    }
                    getOnlinePlayerIdsMessage.notify();
                }
                break;
            }
            case GM_SHUTUP: {
                ShutUpMessage shutUpMessage = (ShutUpMessage)message;
                synchronized(shutUpMessage) {
                    PlayerContext context = GameServer.INSTANCE.playerContexts.get(shutUpMessage.playerId);
                    if(context != null && context.player != null){
                        context.player.endForbidTalkTime = (long)(shutUpMessage.time) * 1000;
                        if(context.player.human != null && context.player.human.inGame){
                            context.player.human.sendMessage(ClientToMapBuilder.buildForbidTalk(context.player.endForbidTalkTime));
                        }
                    }
                    shutUpMessage.notify();
                }
                break;
            }
            case GM_SET_SILVER:
            case GM_SET_GOLD1:
            case GM_SET_GOLD2:
            case GM_EDIT_GOLD1:
            case GM_EDIT_GOLD2:
            case GM_SET_ENERGY:
            case GM_SET_VIP_EXP:
            case GM_SET_LEVEL:
            case GM_ADD_ITEM:
            case GM_REMOVE_ITEM:
            case GM_ADD_CARD:
            case GM_REMOVE_CARD:
            case GM_CHANGE_SANDBOX: {
                RpcModifyPlayerMessage rpcMessage = (RpcModifyPlayerMessage)message;
                synchronized(rpcMessage) {
                    PlayerContext playerContext = GameServer.INSTANCE.playerContexts.get(rpcMessage.playerId);
                    if(playerContext != null ){
                        if(playerContext.human != null){
                            rpcMessage.result = rpcMessage.handler.handle(playerContext.human, rpcMessage.proto);
                            DBMessageQueue.queue().offer(MapDBMessageBuilder.buildSaveCharInfoDBMessage(rpcMessage.playerId, playerContext.human.buildCharDetailInfo()));
                            rpcMessage.notify();
                        } else {
                            playerContext.addWaitingMessage(message);
                        }
                    } else {
                        playerContext = GameServer.INSTANCE.loadPlayerData(rpcMessage.playerId);
                        playerContext.addWaitingMessage(message);
                    }
                }
                break;
            }
            case GM_CHANGE_PLAYER_NAME: {
                RpcModifyPlayerMessage rpcMessage = (RpcModifyPlayerMessage)message;
                synchronized(rpcMessage) {
                    PlayerContext playerContext = GameServer.INSTANCE.playerContexts.get(rpcMessage.playerId);
                    if(playerContext != null ){
                        if(playerContext.human != null){
                            rpcMessage.result = rpcMessage.handler.handle(playerContext.human, rpcMessage.proto);
                            DBMessageQueue.queue().offer(MapDBMessageBuilder.buildChangePlayerNameDBMessage(rpcMessage.playerId, ((IntStringProto)(rpcMessage.proto)).getStringValue()));
                            rpcMessage.notify();
                        } else {
                            playerContext.addWaitingMessage(message);
                        }
                    } else {
                        playerContext = GameServer.INSTANCE.loadPlayerData(rpcMessage.playerId);
                        playerContext.addWaitingMessage(message);
                    }
                }
                break;
            }
            case GM_KICK_PLAYER: {
                KickPlayerMessage killPlayerMessage = (KickPlayerMessage)message;
                synchronized(killPlayerMessage) {
                    MapPlayer player = GameServer.INSTANCE.players.get(killPlayerMessage.playerId);
                    if(player != null){
                        GameServer.INSTANCE.removePlayer(player);
                    }
                    killPlayerMessage.notify();
                }
                break;
            }
            case GM_BROADCAST: {
                BroadcastMessage broadcastMessage = (BroadcastMessage)message;
                synchronized(broadcastMessage) {
                    S2CTalkProto.Builder builder = S2CTalkProto.newBuilder();
                    builder.setChannelType(Consts.SYSTEMCHANNEL);
                    builder.setMsg(broadcastMessage.message);
                    GameServer.INSTANCE.broadcast(ClientToMapBuilder.buildTalk(builder.build().toByteArray()));

                    broadcastMessage.notify();
                }
                break;
            }
            case GM_ADD_MAIL: {
                AddMailMessage addMailMessage = (AddMailMessage)message;
                synchronized(addMailMessage) {
                    GMMailProto mailProto = addMailMessage.mail;
                    
                    MailContentProto content = mailProto.getContent();
                    int targetId = mailProto.getTargetId();
                    String title = content.getTitle();
                    String description = content.getDescription();
                    RewardProto rewardProto = content.hasReward()?content.getReward():null;
                    
                    GameServer.INSTANCE.addMail(targetId, title, description, rewardProto, -1);
                    
                    addMailMessage.notify();
                }
                break;
            }
            case GM_ADD_NORMAL_ACTIVITY: {
                AddNormalActivityMessage addNormalActivityMessage = (AddNormalActivityMessage) message;
                synchronized(addNormalActivityMessage){
                    if(addNormalActivityMessage.hasWriteDB){
                        if(addNormalActivityMessage.response){
                            NormalActivityTemplate template = JSONHelper.parseString(addNormalActivityMessage.activityJsonString, NormalActivityTemplate.class);
                            NormalActivityTemplates.INSTANCE.templates.put(template.staticInfo.id, template);
//                            GameServer.INSTANCE.broadcast(ClientToMapBuilder.buildAddNormalActivity(template.staticInfo.buildNormalActivityProto(0).toByteArray()));
                        }
                        addNormalActivityMessage.notify();

                    } else {
                        AddNormalActivityDBMessage addNormalActivityDBMessage = MapDBMessageBuilder.buildAddNormalActivityDBMessage(addNormalActivityMessage);
                        DBMessageQueue.queue().offer(addNormalActivityDBMessage);
                    }
                }
                
                break;
            }
            case GM_DELETE_NORMAL_ACTIVITY: {
                DeleteNormalActivityMessage deleteNormalActivityMessage = (DeleteNormalActivityMessage)message;
                synchronized(deleteNormalActivityMessage) {
                    if(deleteNormalActivityMessage.hasWriteDB){
                        if(deleteNormalActivityMessage.response){
                            NormalActivityTemplates.INSTANCE.templates.remove(deleteNormalActivityMessage.activityId);
                        }
                        deleteNormalActivityMessage.notify();
                        //GameServer.INSTANCE.broadcast(ClientToMapBuilder.buildDeleteNormalActivity(deleteNormalActivityMessage.activityId));
                    } else {
                        DeleteNormalActivityDBMessage deleteNormalActivityDBMessage = MapDBMessageBuilder.buildDeleteNormalActivityDBMessage(deleteNormalActivityMessage);
                        DBMessageQueue.queue().offer(deleteNormalActivityDBMessage);
                    }
                }
                break;
            }            
            case GM_GET_CONSUMER_LOG: {
                GetConsumerLogMessage getConsumerLogMessage = (GetConsumerLogMessage)message;
                synchronized(getConsumerLogMessage) {
                    GMConsumerLogProto consumerLogProto = getConsumerLogMessage.consumerLog;
                    getConsumerLogMessage.response = GameServer.INSTANCE.GetConsumerLog(consumerLogProto.getCid(), consumerLogProto.getChargeType(),
                            consumerLogProto.getBeginTime(), consumerLogProto.getEndTime());
                    getConsumerLogMessage.notify();
                }
                break;
            }
            case GM_SET_CARD_DRAW_ACTIVITY: {
                SetCardDrawActivityMessage setCardDrawActivityMessage = (SetCardDrawActivityMessage)message;
                synchronized(setCardDrawActivityMessage) {
                    try {
                        JSONCardDrawActivityTemplates jsonCardDrawActivityTemplates = JSONHelper.parseString(setCardDrawActivityMessage.activityJsonString, JSONCardDrawActivityTemplates.class);

                        jsonCardDrawActivityTemplates.buildCardDrawActivityTemplates();
                        
                        setCardDrawActivityMessage.response = true;
                    } catch (JsonSyntaxException e) {
                        // 记录JSON parse出错
                        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                                FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                                "JSON parse error in GMHandler.handler() when handle GM_SET_CARD_DRAW_ACTIVITY message: " + StackTraceUtil.getStackTrace(e)));
                    }

                    setCardDrawActivityMessage.notify();
                }
                break;
            }
            case GM_SET_STAGE_ACTIVITY: {
                SetStageActivityMessage setStageActivityMessage = (SetStageActivityMessage)message;
                synchronized(setStageActivityMessage) {
                    try {
                        JSONStageActivityTemplates jsonStageActivityTemplates = JSONHelper.parseString(setStageActivityMessage.activityJsonString, JSONStageActivityTemplates.class);

                        jsonStageActivityTemplates.buildStageActivityTemplates();

                        setStageActivityMessage.response = true;
                    } catch (JsonSyntaxException e) {
                        // 记录JSON parse出错
                        GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                                FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                                "JSON parse error in GMHandler.handler() when handle GM_SET_STAGE_ACTIVITY message: " + StackTraceUtil.getStackTrace(e)));
                    }

                    setStageActivityMessage.notify();
                }
                break;
            }
        }
    }
}
